package com.buka.recipe.security.provider;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpStatus;
import com.alibaba.fastjson2.JSONObject;
import com.buka.recipe.security.token.WechatAuthenticationToken;
import com.buka.recipe.system.entity.User;
import com.buka.recipe.system.service.UserService;
import lombok.extern.log4j.Log4j2;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@Log4j2
public class WechatAuthenticationProvider implements AuthenticationProvider {

    public static final String WECHAT_LOGIN_URL = "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code";

    private final UserService userService;

    public WechatAuthenticationProvider(UserService userService) {
        this.userService = userService;
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        // 得到Code号
        Object principal = authentication.getPrincipal();
        String code = "";
        if (principal instanceof String) {
            code = (String) principal;
        }
        String openId = wechatLoginRequest(code);
        User user = userService.getUserByOpenid(openId);
        if (user == null) {
            log.debug("Failed to find user, need register...");
            user = new User();
            user.setDepartment(null);
            user.setUsername(RandomUtil.randomString(15));
            user.setPassword(new BCryptPasswordEncoder().encode("dfs444444444222222"));
            user.setNickname("微信用户" + RandomUtil.randomString(6));
            userService.save(user);
        }
        // 返回一个已认证的Token
        final WechatAuthenticationToken newToken = WechatAuthenticationToken.authenticated(openId, user, null);
        // 复制之前token的details
        newToken.setDetails(authentication.getDetails());
        return newToken;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return WechatAuthenticationToken.class.isAssignableFrom(authentication);
    }

    /**
     * 微信登录请求
     *
     * @param code wx.login()获取的code
     * @return openid
     */
    private static String wechatLoginRequest(String code) {
        String url = String.format(WECHAT_LOGIN_URL, "wx0c3a552c65f4607e", "2c174b11786a41cedc0390348bb49e09", code);
        // 请求地址
        log.info("url: {}", url);
        // 发送登录请求
        HttpResponse httpResponse = HttpRequest.get(url).executeAsync();
        String body = httpResponse.body();
        log.info("wechat login result status: {}, body: {}", httpResponse.getStatus(), body);
        if (httpResponse.getStatus() == HttpStatus.HTTP_OK) {
            JSONObject result = JSONObject.parseObject(body);
            if (result.containsKey("openid")) {
                return result.getString("openid");
            } else {
                return "dddaaaccceeeasdfdee";
            }
        }
        throw new AuthenticationServiceException("响应解析失败");
    }
}
